package org.jdemo.util;


import org.apache.commons.io.FileUtils;

import java.io.*;
import java.util.zip.GZIPOutputStream;

/**
 * IOUtil
 *
 * @author longlin(longlin@cyou-inc.com)
 * @date 2013-9-16
 * @since V1.0
 */
public class IOUtil {
    public static final String Default_Encoding = "GBK";

    /**
     * 读取文件，返回文件字符串
     * @param fileName
     * @return
     */
    public static String readFile(String fileName, String encoding) {
        try {
            return readFile(new FileInputStream(fileName), encoding);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static String readFile(File file, String encoding) {
        try {
            return readFile(new FileInputStream(file), encoding);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 读取文件，返回文件字符串
     * @param in
     * @param encoding
     * @return
     */
    public static String readFile(InputStream in, String encoding) {
        if(in == null) {
            return null;
        }

        StringBuffer sb = new StringBuffer();
        try {
            InputStreamReader reader = new InputStreamReader(in, encoding);
            int tmp = -1;
            char temp;
            while((tmp=reader.read()) != -1) {
                temp = (char)tmp;
                sb.append(temp);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return sb.toString();
    }

    //根据文件创建目录
    public static boolean makeDir(File file) {
        if(!file.exists()) {
            makeDir(file.getAbsolutePath());
        }
        return true;
    }

    /**
     * 根据文件名创建目录
     * @param fileName
     * @return
     */
    public static boolean makeDir(String fileName) {
        int index = 0;
        int index1 = fileName.lastIndexOf("/");
        int index2 = fileName.lastIndexOf("\\");
        if(index1 > index2){
            index = index1;
        }else {
            index = index2;
        }
        fileName = fileName.substring(0, index);
        File file = new File(fileName);
        if(!file.exists()) {
            if(!file.mkdirs()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 根据路径创建目录
     * @param path
     * @return
     */
    public static boolean makeDirByPath(String path) {
        File file = new File(path);
        if(!file.exists()) {
            if(!file.mkdirs()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 将str写入文件path
     * @param str
     * @param fileName
     * @param append true为追加，false为覆盖
     * @return
     */
    public static boolean writeFile(String str, String fileName, String encoding, boolean append) {
        try {
            if(makeDir(fileName)) {
                FileOutputStream fos = new FileOutputStream(new File(fileName), append);
                Writer out = new OutputStreamWriter(fos, encoding);
                out.write(str);

                out.flush();
                out.close();

                fos.flush();
                fos.close();
            }else {
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 将inputStream写入文件并关闭inputStream
     * @param is
     * @param fileName
     * @param encoding
     * @param append true为追加，false为覆盖
     * @return
     */
    public static boolean writeFile(InputStream is, String fileName, String encoding, boolean append) {
        try {
            if(makeDir(fileName) && is != null) {
                FileOutputStream fos = new FileOutputStream(fileName, append);
                byte[] buffer =new byte[1024*1024];
                //int bytesum = 0;
                int byteread = 0;
                while ((byteread = is.read(buffer))!=-1) {
                    //bytesum+=byteread;
                    fos.write(buffer,0,byteread);
                    fos.flush();
                }
                fos.close();
                is.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * gzip压缩文件
     * @param source
     * @param target
     */
    public static void zipFile(String source, String target) {
        try {
            FileInputStream fin = new FileInputStream(source);
            FileOutputStream fout = new FileOutputStream(target);
            GZIPOutputStream gzout = new GZIPOutputStream(fout);
            byte[] buf = new byte[1024];
            int num;
            while ((num = fin.read(buf)) != -1) {
                gzout.write(buf, 0, num);
            }
            gzout.close();
            fout.close();
            fin.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * copy文件,只使用于文本文件
     * @param srcFileName
     * @param destFileName
     * @param encoding
     * @return
     */
    public static boolean copyTxtFile(String srcFileName, String destFileName, String encoding) {
        try {
            if(makeDir(destFileName)) {
                InputStream in = new FileInputStream(srcFileName);
                InputStreamReader reader = new InputStreamReader(in, encoding);

                PrintWriter out = new PrintWriter(new FileWriter(destFileName, false));

                int tmp = -1;
                char temp;
                while((tmp=reader.read()) != -1) {
                    temp = (char)tmp;
                    out.write(temp);
                }

                in.close();
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 复制二进制文件
     * @param srcFileName 源文件路径
     * @param destFileName	目标文件路径
     * @return
     */
    public static boolean copyOctFile(String srcFileName, String destFileName) {
        try {
            FileUtils.copyFile(new File(srcFileName), new File(destFileName));
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 复制文件夹到文件夹
     * @param srcDir
     * @param destDir
     * @return
     */
    public static boolean copyDirectory(String srcDir, String destDir) {
        try {
            File srcFile = new File(srcDir);
            File destFile = new File(destDir);

            FileUtils.copyDirectoryToDirectory(srcFile, destFile);

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 复制文件夹下的所有文件或文件夹到文件夹（不包括根文件夹）
     * @param srcDir
     * @param destDir
     * @return
     */
    public static boolean copyDirectoryChild(String srcDir, String destDir) {
        try {
            File srcFile = new File(srcDir);
            File destFile = new File(destDir);

            File[] files = srcFile.listFiles();
            for (int i = 0; i < files.length; i++) {
                if(files[i].isDirectory()){
                    FileUtils.copyDirectoryToDirectory(files[i], destFile);
                }else{
                    FileUtils.copyFileToDirectory(files[i], destFile);
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }


    /**
     * 删除目录
     * @param dir
     * @return
     */
    public static boolean deleteDirectory(String dir) {
        return deleteDirectory(new File(dir));
    }

    /**
     * 删除目录
     * @param dir
     * @return
     */
    public static boolean deleteDirectory(File dir) {
        try {
            FileUtils.deleteDirectory(dir);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static boolean deleteFile(String fileName) {
        if(fileName != null && fileName.length() > 0) {
            return deleteFile(new File(fileName));
        }
        return true;
    }

    public static boolean deleteFile(File file) {
        if (file.exists()) {
            file.delete();
        }
        return true;
    }

    public static String getRandomFileName(String fileName) {
        int end = fileName.lastIndexOf(".");
        String extName = fileName.substring(end);
        String newFileName = System.currentTimeMillis() + extName;
        return newFileName;

    }

    public static boolean renameFile(String source , String dest){
        File sourceFile = new File(source);
        File destFile = new File(dest);
        return  sourceFile.renameTo(destFile);
    }

    public static String getAllFileViewTree(File dir , String serverActionPath , StringBuilder sb){
        File[] fs = dir.listFiles();

        for (int i = 0; i < fs.length; i++) {
            sb.append("{");
            if (fs[i].isDirectory()) {
                sb.append("\"text\":\"").append(fs[i].getName()).append("&nbsp;&nbsp;&nbsp;<a href='/").append(serverActionPath)
                        .append("?path='").append(fs[i].getAbsolutePath()).append("'>编辑</a>\",");
                sb.append("\"expanded\":true,");
                sb.append("\"classes\":\"folder\",");
                sb.append("\"children\":[");
                try {
                    getAllFileViewTree(fs[i] , serverActionPath , sb);
                } catch (Exception e) {
                }
                sb.append("]");
            }else{
                sb.append("\"text\":\"").append(fs[i].getName()).append("&nbsp;&nbsp;&nbsp;<a href='/").append(serverActionPath)
                        .append("?path='").append(fs[i].getAbsolutePath()).append("'>编辑</a>\",");
                sb.append("\"classes\":\"file\"");
            }
            sb.append("}");
            if(i < fs.length - 1){
                sb.append(",");
            }
        }

        return sb.toString();
    }

    public static String getFilePath(String dirPath, String fileName) {
        if(dirPath == null || dirPath.equals("")) {
            return fileName;
        }

        String filePath;
        dirPath = dirPath.replaceAll("\\\\", "/");
        if(dirPath.endsWith("/")) {
            filePath = dirPath + fileName;
        }else {
            filePath = dirPath + "/" + fileName;
        }
        return filePath;
    }

    public static String getFileSuffix(String filePath) {
        if(filePath.indexOf(".") != -1) {
            String[] array = filePath.split("\\.");
            return array[array.length - 1].toLowerCase();
        }
        return null;
    }


    public static void allGbkToUtf8(File dir){
        FileFilter fileFilter=new FileFilter(){
            public boolean accept(File pathname) {
                String tmp=pathname.getName().toLowerCase();
                if(tmp.equals(".svn")){
                    return false;
                }
                if(pathname.isFile() && !tmp.endsWith(".java")){
                    return false;
                }
                return true;
            }
        };
        if(dir.isDirectory()){
            File[] files = dir.listFiles(fileFilter);
            for (File file : files) {
                if(file.isDirectory()){
                    allGbkToUtf8(file);
                }else {
                    writeFile(readFile(file, "gbk"), file.getAbsolutePath(), "utf-8", false);
                }
            }
        }

    }
}
